package admin_service

import (
	"fmt"
	"github.com/cihub/seelog"
	"shop/config/constant"
	"shop/dao"
	"shop/entity"
	"shop/service"
	"shop/utils/convertutil"
	"shop/utils/genutil"
	"shop/utils/result"
	"shop/utils/wxpay"
)

func GetOrderList(shopId, pageNo, pageSize, orderStatus int) *result.Result {
	db := dao.GetDB().Table(entity.TableNameOrderInfo).Where("shop_id", shopId)
	if orderStatus == constant.OrderStatusRefunding || orderStatus == constant.OrderStatusRefunded {
		db.Where("refund_count > 0")
	} else if orderStatus != 0 {
		db.Where("order_status", orderStatus)
	}
	count := new(int64)
	db.Count(count)
	list := make([]*entity.OrderInfo, 0, 0)
	db.Offset((pageNo - 1) * pageSize).Limit(pageSize).Find(&list)
	for _, order := range list {
		order.ParseGoodsList()
	}
	return result.Ok(entity.Page{
		Total: *count,
		List:  list,
	})
}

const (
	CancelAndDelete = 1 // 取消并删除订单
	SendGoods       = 2 // 发货
	Refund          = 3 // 退款
)

type UpdateOrderStatusParams struct {
	OrderNo        string `json:"orderNo,omitempty"`
	Command        int    `json:"command,omitempty"`
	RefundReason   string `json:"refundReason,omitempty"` // 退款时需要
	RefundGoodsMap []bool `json:"refundGoodsMap,omitempty" `
}

func UpdateOrderStatus(shopId int, params *UpdateOrderStatusParams) *result.Result {
	seelog.Debugf("更新订单状态：%v", convertutil.ToJsonString(params))
	order := new(entity.OrderInfo)
	tx := dao.GetTx().Model(&order).Where("order_no=? and shop_id=?", params.OrderNo, shopId).Take(order)
	if order.OrderNo == "" {
		return result.Fail("订单不存在")
	}

	if params.Command == CancelAndDelete {
		if order.OrderStatus != constant.OrderStatusNotPay {
			return result.Fail("未付款的订单才能取消")
		}
		rows := tx.Where("order_no", order.OrderNo).Delete(nil).Commit().RowsAffected
		return result.Ok(rows)
	} else if params.Command == SendGoods {
		if order.OrderStatus != constant.OrderStatusWaitSend {
			return result.Fail("待发货的订单才能发货")
		}
		rows := tx.Where("order_no", order.OrderNo).UpdateColumn("order_status", constant.OrderStatusWaitTake).Commit().RowsAffected
		return result.Ok(rows)
	} else if params.Command == Refund {
		if order.OrderStatus == constant.OrderStatusNotPay || order.OrderStatus == constant.OrderStatusFinished {
			return result.Fail("未付款和已完成的订单不支持退款")
		}
		order.ParseGoodsList()
		if params.RefundGoodsMap == nil || len(params.RefundGoodsMap) != len(order.GoodsList) {
			return result.Fail("退款商品参数格式错误")
		}
		order.RefundCount = 0
		refundPrice := int64(0)
		refundNo := order.OrderNo + "-" + genutil.RandStr(10) // 本次退款的退款号
		for i, orderGoods := range order.GoodsList {
			if params.RefundGoodsMap[i] && orderGoods.RefundNo == "" {
				orderGoods.RefundNo = refundNo
				orderGoods.RefundReason = params.RefundReason
				refundPrice += int64(orderGoods.Price * orderGoods.Count)
			}
			if orderGoods.RefundNo != "" {
				order.RefundCount++
			}
		}
		if refundPrice == 0 {
			return result.Fail("退款价格为0")
		}
		shop := service.GetShopById(shopId)
		cli := wxpay.NewClient(shop.WxMpAppId, shop.WxPayMchId, shop.WxPayApiKey)
		cli.SetCertData(shop.CertPEMPublicKey, shop.CertPEMPrivateKey)
		_, err := cli.Refund(&wxpay.RefundParams{
			TransactionId: order.WxPayTransactionId,
			OutRefundNo:   refundNo,
			TotalFee:      order.PayPrice,
			RefundFee:     refundPrice,
		})
		if err != nil {
			return result.Fail("退款失败，" + err.Error())
		}
		if order.RefundCount == len(order.GoodsList) { // 全部商品都要退款，订单状态就改为退款中
			order.OrderStatus = constant.OrderStatusRefunded
		}
		order.PayPrice -= refundPrice
		order.GoodsListToStr()
		rows := tx.Model(order).Where("order_no", order.OrderNo).Updates(order).Commit().RowsAffected
		return result.Ok(rows)
	}
	return result.Fail(fmt.Sprintf("不支持的命令：%d", params.Command))
}
